package repository

import (
	"ai-curd/oo"
	"ai-curd/repository/ent"
	"ai-curd/repository/ent/article"
	"context"
)

func (repo *Article) Fetch(ctx context.Context, id int) oo.Article {
	return repo.FetchOne(ctx, func(query *ent.ArticleQuery) {
		query.Where(article.ID(id))
	})
}

func (repo *Article) FetchOne(ctx context.Context, optionFunc func(query *ent.ArticleQuery)) oo.Article {
	return repo.fetchOne(ctx, repo.db, optionFunc).Mapper()
}

func (repo *Article) fetchOne(ctx context.Context, db *ent.Client, optionFunc func(query *ent.ArticleQuery)) *ent.Article {
	builder := db.Article.Query()
	optionFunc(builder)
	return builder.FirstX(ctx)
}

func (repo *Article) FetchMany(ctx context.Context, optionFunc func(query *ent.ArticleQuery)) oo.Articles {
	return repo.fetchMany(ctx, repo.db, optionFunc).Mapper()
}

func (repo *Article) fetchMany(ctx context.Context, db *ent.Client, optionFunc func(query *ent.ArticleQuery)) ent.Articles {
	builder := db.Article.Query()
	optionFunc(builder)
	return builder.AllX(ctx)
}

func (repo *Article) Count(ctx context.Context, option func(query *ent.ArticleQuery)) int {
	return repo.count(ctx, repo.db, option)
}

func (repo *Article) count(ctx context.Context, db *ent.Client, option func(query *ent.ArticleQuery)) int {
	builder := db.Article.Query()
	option(builder)
	return builder.CountX(ctx)
}

func (repo *Article) Exist(ctx context.Context, option func(query *ent.ArticleQuery)) bool {
	return repo.exist(ctx, repo.db, option)
}

func (repo *Article) exist(ctx context.Context, db *ent.Client, option func(query *ent.ArticleQuery)) bool {
	builder := db.Article.Query()
	option(builder)
	return builder.ExistX(ctx)
}

func (repo *Article) Create(ctx context.Context, option func(query *ent.ArticleCreate)) oo.Article {
	return repo.create(ctx, repo.db, option).Mapper()
}

func (repo *Article) create(ctx context.Context, db *ent.Client, option func(query *ent.ArticleCreate)) *ent.Article {
	builder := db.Article.Create()
	option(builder)
	return builder.SaveX(ctx)
}

func (repo *Article) Update(ctx context.Context, option func(query *ent.ArticleUpdate)) int {
	return repo.update(ctx, repo.db, option)
}

func (repo *Article) update(ctx context.Context, db *ent.Client, option func(query *ent.ArticleUpdate)) int {
	builder := db.Article.Update()
	option(builder)
	return builder.SaveX(ctx)
}

func (repo *Article) Delete(ctx context.Context, option func(query *ent.ArticleDelete)) int {
	return repo.delete(ctx, repo.db, option)
}

func (repo *Article) delete(ctx context.Context, db *ent.Client, option func(query *ent.ArticleDelete)) int {
	builder := db.Article.Delete()
	option(builder)
	return builder.ExecX(ctx)
}

func (repo *Article) Save(ctx context.Context, ooArticle oo.Article) oo.Article {
	return repo.save(ctx, repo.db, ooArticle).Mapper()
}

func (repo *Article) save(ctx context.Context, db *ent.Client, ooArticle oo.Article) *ent.Article {
	builder := db.Article.Create()
	ooArticle.CategoryIsPresent(func(v int) { builder.SetCategory(v) })
	ooArticle.TitleIsPresent(func(v string) { builder.SetTitle(v) })
	ooArticle.ContentIsPresent(func(v string) { builder.SetContent(v) })
	return builder.SaveX(ctx)
}

func (repo *Article) Modify(ctx context.Context, ooArticle oo.Article) int {
	return repo.modify(ctx, repo.db, ooArticle)
}

func (repo *Article) modify(ctx context.Context, db *ent.Client, ooArticle oo.Article) int {
	builder := db.Article.Update()
	ooArticle.CategoryIsPresent(func(v int) { builder.SetCategory(v) })
	ooArticle.TitleIsPresent(func(v string) { builder.SetTitle(v) })
	ooArticle.ContentIsPresent(func(v string) { builder.SetContent(v) })
	return builder.Where(article.ID(ooArticle.ID())).SaveX(ctx)
}
